package com.wjbgn.trading.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wjbgn.stater.dto.Result;
import com.wjbgn.stater.enums.CommonReturnEnum;
import com.wjbgn.stater.enums.OrderStatusEnum;
import com.wjbgn.stater.enums.TradingStatusEnum;
import com.wjbgn.trading.client.OrderClient;
import com.wjbgn.trading.client.UserAccountClient;
import com.wjbgn.trading.client.dto.OrderDTO;
import com.wjbgn.trading.client.dto.UserAccountDTO;
import com.wjbgn.trading.entity.TradingDO;
import com.wjbgn.trading.mapper.TradingMapper;
import com.wjbgn.trading.service.TradingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Description:
 * Create Date: 2022-01-19T15:33:09.329
 *
 * @author weirx
 * @version 1.0
 */
@Slf4j
@Service
public class TradingServiceImpl extends ServiceImpl<TradingMapper, TradingDO> implements TradingService {

    @Autowired
    private OrderClient orderClient;

    @Autowired
    private UserAccountClient userAccountClient;

    @Override
    public Result trading(TradingDO tradingDO) {
        OrderDTO orderDTO = this.updateOrder(tradingDO);
        if (ObjectUtil.isNull(orderDTO)) {
            log.info("支付失败,修改订单状态失败,订单id :{}", tradingDO.getOrderId());
            return Result.failed("支付失败,修改订单状态失败");
        }

        // 扣减用户账户金额
        Result result = userAccountClient.accountDeducting(new UserAccountDTO(orderDTO.getUserId(), orderDTO.getOrderAmount()));
        if (result.getCode() != CommonReturnEnum.SUCCESS.getCode()) {
            log.info("用户账户扣款失败,订单id :{}", tradingDO.getOrderId());
            return Result.failed("用户账户扣款失败");
        }
        // 生成支付订单
        tradingDO.setCreateUser(1L);
        tradingDO.setTradingAmount(orderDTO.getOrderAmount());
        tradingDO.setTradingStatus(TradingStatusEnum.SUCCESS);
        tradingDO.setUserId(orderDTO.getUserId());
        boolean save = this.save(tradingDO);
        if (!save) {
            //修改用户订单状态 - 支付失败
            orderClient.update(new OrderDTO(tradingDO.getOrderId(), OrderStatusEnum.PAY_FAILED.toString()));
            //TODO 回滚用户的账户金额
        } else {
            //修改用户订单状态 - 订单完成
            orderClient.update(new OrderDTO(tradingDO.getOrderId(), OrderStatusEnum.FINNISH.toString()));
        }
        return Result.success("支付成功");
    }

    /**
     * description: 验证并更新订单状态
     * @param tradingDO
     * @return: com.wjbgn.trading.client.dto.OrderDTO
     * @author: weirx
     * @time: 2022/2/21 16:34
     */
    OrderDTO updateOrder(TradingDO tradingDO) {
        // 获取订单信息
        Result info = orderClient.info(tradingDO.getOrderId());
        if (ObjectUtil.isEmpty(info.getData())) {
            return null;
        }
        OrderDTO orderDTO = JSONObject.parseObject(JSONObject.toJSONString(info.getData())).toJavaObject(OrderDTO.class);
        //已完成订单不能再次支付
        if (orderDTO.getOrderStatus().equals(OrderStatusEnum.FINNISH.getCode())) {
            return null;
        }
        //修改用户订单状态 - 支付中
        Result update = orderClient.update(new OrderDTO(tradingDO.getOrderId(), OrderStatusEnum.PAYING.toString()));
        if (update.getCode() != CommonReturnEnum.SUCCESS.getCode()) {
            return null;
        }
        return orderDTO;
    }
}